#include <iostream>
using namespace std;

//对象移动
/**
 * 对象拷贝c++11“对象移动”
 * 1. a移动到b，那么a就不能再使用了
 * 2.移动并不是把内存中的地址倒腾到另外一个地址，只是所有者变更
 *
 *  3移动构造函数
 *  Time(Time&&temp)//右值引用，使用之后，源对象就不再使用了 
 * 
 * 移动构造和移动赋值运算符完成的阿任务
 *  1.斩断a对象和b对象的关系
 * 2.确保即使销毁源对象，也每什么问题
 * 
 * **/



class B{
public:
    B(){

        m_bm=new B();
    }
    //拷贝构造
    B(const B&b){
        this->m_bm=b.m_bm;
    }
    //拷贝赋值

    B& operator=(const B&src){
        if(this==&src){
            return *this;
        }
        delete m_bm;
        m_bm=new B(*(src.m_bm));

    }

    //移动构造
    B(B&&temp)noexcept:m_bm(temp.m_bm)
    {
        //temp赋值给新的对象后，要断开原先的连接
        temp.m_bm=NULL;

        //将对象移动给另一个对象
        std::cout<<"移动构造"<<std::endl;

    }

    //移动赋值运算符
    B& operator=(B&&src) noexcept{
        if(this==&src){
            return*this;
        }
        //把自己内存先干掉
        delete m_bm;
        //对方内存拿过来
        m_bm=src.m_bm;
        //斩断源
        src.m_bm=nullptr;
          
        return *this;



    }

    virtual ~B(){ 
        delete m_bm;
    }

public:
    B* m_bm;
};



void test(){
    // B*pb=new B();
    // pb.m_bm=19;
    // B*pb2=new B(*pb);

    // delete pb;
    // delete pb2;

    B b;
    B c(b);//如果不加std::move()则调用拷贝构造函数

    //这个会创新新的对象
    B d(std::move(b));//使用移动构造函数，这里相当于创新新的对象
    B&&e(std::move(b));//这个相当于该了别名，并没有创建新的对象


}


